FCNTL(2) | Руководство программиста Linux | FCNTL(2) |
НАЗВАНИЕ¶
fcntl - манипуляция файловым дескриптором
КРАТКАЯ СВОДКА¶
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock);
ОПИСАНИЕ¶
fcntl выполняет одну из разнообразных операций с файловым дескриптором fd. Какую именно -- определяется параметром cmd:
- F_DUPFD
- Ищет
первый
доступный
файловый
дескриптор,
больший
или равный
arg, и делает
его копией
fd.
Это поведение отличается от dup2(2), которая использует именно заданный файловый дескриптор.
Старый и новый дескриптор могут использоваться друг вместо друга. У них общие блокировки, положение указателя в файле и флаги; например, если положение указателя изменяется с помощью lseek на одном из дескрипторов, то оно также меняется на другом.
Два дескриптора, однако, не делят флаг закрыть-при-exec. У копии этот флаг будет установлен в ноль, означая, что он не будет закрыт при выполнении exec.
При успешном завершении возвращается новый дескриптор.
- F_GETFD
- Получить состояние флага закрыть-при-exec. Если бит FD_CLOEXEC результата равен нулю, то файл будет оставаться открытым после выполнения exec, в противном случае он закроется.
- F_SETFD
- Установить флаг закрыть-при-exec, как указано в бите FD_CLOEXEC параметра arg.
- F_GETFL
- Прочитать флаги дескриптора (возвращаются все флаги, установленные при помощи open(2)).
- F_SETFL
- Установить
флаги
дескриптора
в значение,
заданное
при помощи
arg. Можно
установить
только
флаги O_APPEND,
O_NONBLOCK и O_ASYNC,
прочие
флаги не
будут
затронуты.
Флаги являются общими для копий файлового дескриптора, сделанных с помощью dup(2), fork(2), и т. д.
Флаги и их семантика описаны в open(2).
F_GETLK, F_SETLK и F_SETLKW используются для управления "мягкими" файловыми блокировками. Третий аргумент, lock, является указателем на struct flock (которая может быть перезаписана этим системным вызовом).
- F_GETLK
- Возвращает структуру flock, которая мешает нам получить свою собственную блокировку, или установить поле l_type в значение F_UNLCK, если других блокировок нет.
- F_SETLK
- Блокировка устанавливается (если поле l_type равно F_RDLCK или F_WRLCK) или очищается (если это поле равно F_UNLCK). Если блокировка установлена кем-то ещё, этот вызов возвращает -1 и устанавливает errno в EACCESS или EAGAIN.
- F_SETLKW
- Аналогично F_SETLK, только вместо возвращения кода ошибки ожидает, пока блокировка не будет снята. Если в процессе ожидания приходит сигнал, то системный вызов прерывается и, после того, как отработал обработчик сигнала, немедленно возвращает -1 и устанавливает errno в EINTR.
F_GETOWN, F_SETOWN, F_GETSIG и F_SETSIG используются для управления сигналами доступности ввода/вывода:
- F_GETOWN
- Получить идентификатор процесса или группы процессов, получающих сигналы SIGIO и SIGURG для событий на файловом дескрипторе fd. Группы процессов возвращаются как отрицательные значения.
- F_SETOWN
- Установить
идентификатор
процесса
или группы
процессов,
которые
будут
получать
сигналы SIGIO
и SIGURG для
событий на
файловом
дескрипторе
fd. Группы
процессов
задаются
как
отрицательные
значения.
(F_SETSIG может
использоваться
для
задания
другого
сигнала
вместо SIGIO).
Если вы установите флаг O_ASYNC на файловом дескрипторе (передав этот флаг при вызове open(2) или используя команду F_SETFL при вызове fcntl), то сигнал SIGIO будет посылаться каждый раз, когда на этом файловом дескрипторе становится возможен ввод и вывод.
Процесс или группа процессов, которые будут получать сигнал, могут быть выбраны с помощью команды F_SETOWN функции fcntl. Если файловый дескриптор -- это сокет, то при этом будет также выбран адресат сигналов SIGURG, которые посылаются, когда по сокету приходят данные вне основного канала. (SIGURG отсылается в любой ситуации, когда select(2) сообщила бы, что в сокете наличествует "исключительная ситуация".) Если файловый дескриптор соответствует терминальному устройству, то сигналы SIGIO посылаются группе процессов на терминале, выполняющихся не в фоне.
- F_GETSIG
- Узнать, какой сигнал посылается, когда становится возможным ввод или вывод. Ноль означает, что посылается SIGIO. Любое другое значение (включая SIGIO) -- это сигнал, который посылается вместо SIGIO, в этом случае доступна дополнительная информация, если обработчик сигнала был установлен с использованием SA_SIGINFO.
- F_SETSIG
- Задает
сигнал,
который
посылается,
когда
становится
возможным
ввод или
вывод.
Значение
ноль
означает,
что нужно
посылать
стандартный
сигнал SIGIO.
Любое
другое
значение
(включая SIGIO),
означает,
что нужно
послать
другой
сигнал, и в
этом
случае
также
доступна
дополнительная
информация,
если
обработчик
сигнала
был
установлен
с SA_SIGINFO.
Используя F_SETSIG вместе с ненулевым значением и задавая обработчику сигнала флаг SA_SIGINFO (см. sigaction(2)), можно передать этому обработчику дополнительную информацию о событиях ввода-вывода с помощью структуры siginfo_t. Если поле si_code задает, что источником является SI_SIGIO, то поле si_fd содержит файловый дескриптор, на котором произошло событие. В противном случае нет прямого указания, какие именно файловые дескрипторы участвуют в происходящем, поэтому нужно использовать обычные механизмы (select(2), poll(2), read(2) с флагом O_NONBLOCK, и так далее), чтобы определить, для каких дескрипторов доступен ввод-вывод.
Выбрав сигнал реального времени, соответствующий стандарту POSIX (значение >= SIGRTMIN), можно использовать очереди из множества событий ввода-вывода, использующих один и тот же номер сигнала. (Построение очереди зависит от доступной памяти). Дополнительная информация доступна, если для обработчика установлен SA_SIGINFO, как описано выше.
Используя эти механизмы, можно реализовать полностью асинхронный ввод-вывод без использования, по большей части, select(2) или poll(2).
Использование O_ASYNC, F_GETOWN, F_SETOWN специфично для систем BSD и Linux. F_GETSIG и F_SETSIG специфичны для Linux. POSIX включает в себя асинхронный ввод-вывод и структуру aio_sigevent, с помощью которой достигаются подобные вещи; они также доступны под Linux как часть библиотеки GNU C (Glibc).
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном завершении возвращаемое значение зависит от операции:
- F_DUPFD
- Новый дескриптор.
- F_GETFD
- Значение флага.
- F_GETFL
- Значение флагов.
- F_GETOWN
- Владелец дескриптора.
- F_GETSIG
- Номер сигнала, который посылается, когда появляется возможность читать или писать, или же ноль, означающий традиционное поведение, сигнал SIGIO.
- Все другие команды
- Нуль.
При ошибке возвращается -1, а errno устанавливается должным образом.
ОШИБКИ¶
- EACCES
- Операция запрещена блокировкой, установленной другим процессом.
- EAGAIN
- Операция запрещена, потому что файл был отображен в память другим процессом.
- EBADF
- fd не является открытым файловым дескриптором.
- EDEADLK
- Обнаружено, что заданная команда F_SETLKW вызвала бы мертвую блокировку.
- EFAULT
- lock указывает за пределы доступного адресного пространства.
- EINTR
- Команда F_SETLKW была прервана сигналом. Команды F_GETLK и F_SETLK, были прерваны сигналом, пока блокировка еще не была проверена или установлена. Чаще всего случается при блокировке сетевого файла (например, при работе с NFS), но иногда может случиться и локально.
- EINVAL
- Команда F_DUPFD: arg отрицателен или больше, чем максимально разрешенное значение. Команда F_SETSIG: arg не является разрешенным номером сигнала.
- EMFILE
- Команда F_DUPFD: процесс уже открыл максимальное количество файловых дескрипторов.
- ENOLCK
- Открыто слишком много сегментных блокировок, таблица блокировок полна или же произошла ошибка при сетевой блокировке (при работе с NFS).
- EPERM
- Попытка очистить флаг O_APPEND на файле, имеющем атрибут "только-добавление".
ЗАМЕЧАНИЯ¶
Ошибки, которые возвращает dup2, отличаются от тех, что возвращает F_DUPFD.
СООТВЕТСТВИЕ СТАНДАРТАМ¶
SVr4, SVID, POSIX, X/OPEN, BSD 4.3. В POSIX.1 указаны только операции F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK и F_SETLKW. F_GETOWN и F_SETOWN являются BSD-измами, которые не поддерживаются в SVr4; F_GETSIG и F_SETSIG специфичны для Linux. Флаги, допустимые для F_GETFL/F_SETFL -- те, что поддерживаются системным вызовом open(2), и они отличаются на разных системах; O_APPEND, O_NONBLOCK, O_RDONLY, и O_RDWR указаны в POSIX.1. SVr4 поддерживает несколько других опций и флагов, не документированных здесь.
SVr4 документирует дополнительные коды ошибок EIO, ENOLINK и EOVERFLOW.
СМОТРИ ТАКЖЕ¶
ПЕРЕВОД¶
Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 1999
12 July 1999 | Linux |